package pers.vic.elasticsearch.model;

import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import org.springframework.util.Assert;
import pers.vic.boot.base.lookup.Lookup;

/**
 * @author Vic.xu
 * @description: ES 分页查询条件
 * 可以用如下方式构建
 * <pre>
  		EsLookup<EsTesting> lookup = EsLookup.build("indexName", EsTesting.class).keyword("keyword").page(1, 2)
				.addHighlightFieldAndSetFunctionString("name", (model, name) -> {
					model.setName(name);
				}).addHighlightFieldAndSetFunctionString("remark", (model, name) -> {
					model.setName(name);
				}).end();
 * </pre>
 * 
 * 
 * @date: 2020/6/22 0022 13:23
 */
public class EsLookup<T> extends Lookup {
	private static final long serialVersionUID = 1L;

	/**
	 * 索引
	 */
	public String indexName;
	/**
     * 关键字
     */
    private String keyword;

    /**
     * 滚动分页的id ;暂时未使用
     */
    private String scrollId;
    
    /**
     * 查询结果对象
     */
    private Class<T> clazz;
    
    /**
     * key为需要高亮字段，value为对应的set函数<br/>
     * eg： key:    title
     *     value :  (model, text)->{mode.setTitle(text)}
     */
    private Map<String, BiConsumer<T,String>> highlightFieldAndSetFunctionMap =new HashMap<String, BiConsumer<T,String>>();
    
    /**
     * 构建lookup的入口
     * @param <T> 泛型
     * @param indexName 索引名
     * @param clazz 返回的model类型
     * @return
     */
    public static <T> EsLookup<T> build(String indexName, Class<T> clazz){
    	EsLookup<T> lookup = new EsLookup<T>();
    	lookup.setIndexName(indexName);
    	lookup.setClazz(clazz);
    	return lookup;
    }
    
    /**
     * 构建关键词
     * @param keyword 搜索的关键词
     */
    public EsLookup<T> keyword(String keyword){
    	this.keyword = keyword;
    	return this;
    }
    
    /**
     * 构建分页
     * @param page 页码
     * @param size 每页数量
     */
    public EsLookup<T> page(int page, int size){
    	this.setPage(page);
    	this.setSize(size);
    	return this;
    }
    
    /**
     * 构建高亮字段，以及高亮字段的set方法
     * @param field 高亮字段名
     * @param bc 字段名的set方法
     */
    public EsLookup<T> addHighlightFieldAndSetFunctionString(String field, BiConsumer<T,String> bc){
    	highlightFieldAndSetFunctionMap.put(field, bc);
    	return this;
    }
    /**
     * 构建高亮字段，以及高亮字段的set方法
     * @param map  高亮字段名->字段名的set方法
     */
    public EsLookup<T> addHighlightFieldAndSetFunctionString(Map<String, BiConsumer<T,String>> map){
    	highlightFieldAndSetFunctionMap.putAll(map);
    	return this;
    }
    
    /**
     * 结束构建lookup并检测合法性
     */
    public EsLookup<T> end(){
    	Assert.hasText(keyword, "keyword不可为空");
    	Assert.hasText(indexName, "indexName不可为空");
    	Assert.isTrue(highlightFieldAndSetFunctionMap.size() > 0 , "必须包含高亮字段，以及对应的set方法");
    	return this;
    }
    

    public String getKeyword() {
        return keyword;
    }

    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }

	public String getScrollId() {
		return scrollId;
	}

	public void setScrollId(String scrollId) {
		this.scrollId = scrollId;
	}
	
	@SuppressWarnings("unchecked")
	public Class<T> getClazz() {
		if(clazz == null) {
			clazz = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
		}
		return clazz;
	}

	public void setClazz(Class<T> clazz) {
		this.clazz = clazz;
	}

	public Map<String, BiConsumer<T, String>> getHighlightFieldAndSetFunctionMap() {
		return highlightFieldAndSetFunctionMap;
	}

	public void setHighlightFieldAndSetFunctionMap(Map<String, BiConsumer<T, String>> highlightFieldAndSetFunctionMap) {
		this.highlightFieldAndSetFunctionMap = highlightFieldAndSetFunctionMap;
	}

	public String getIndexName() {
		return indexName;
	}

	public void setIndexName(String indexName) {
		this.indexName = indexName;
	}

	
	
    
    
}
